package com.wzy.controller;

import com.wzy.tree.ManyTreeNode;
import com.wzy.tree.TreeNode;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @Author: wzy
 * @Date: 2022/01/02/17:29
 * @Description:
 */
public class TestManyTree {
    public static void main(String[] args) {
        ManyTreeNode manyTree = createManyTree();
        Map<String, Map<String, List<String>>> map = ZZ(manyTree);
        System.out.println(map);
        List<ManyTreeNode> list = new ArrayList<>();
        orgRecursion(list, manyTree.getChildList(), "1");
        // System.out.println(list);
        for (ManyTreeNode manyTreeNode : list) {
            System.out.print(manyTreeNode.getData().getId());
        }
        System.out.println();
        List<ManyTreeNode> list1 = new ArrayList<>();
        List<ManyTreeNode> manyTreeNodes = treeMenuList(list1, manyTree.getChildList(), "2");
        System.out.println("------");
        Map<String, List<String>> resultMap = new HashMap<>();
        for (ManyTreeNode manyTreeNode : manyTreeNodes) {
            TreeNode treeNode = manyTreeNode.getData();
            List<ManyTreeNode> list2 = new ArrayList<>();
            List<ManyTreeNode> child = Optional.ofNullable(manyTreeNode.getChildList()).orElse(list2);
            list2 = treeMenuList(list2, child, "3");
            ArrayList<String> strings = new ArrayList<>();
            for (ManyTreeNode node : list2) {
                strings.add(node.getData().getId());
            }
            resultMap.put(treeNode.getId(), strings);
        }
        System.out.println(resultMap);
        // System.out.println(manyTreeNodes);
    }

    /**
     * 获取某个父节点下面的所有子节点
     *
     * @param menuList
     * @param position
     * @return
     */
    public static List<ManyTreeNode> treeMenuList(List<ManyTreeNode> childMenu, List<ManyTreeNode> menuList, String position) {
        for (ManyTreeNode mu : menuList) {
            //遍历出父id等于参数的id，add进子节点集合
            if (mu.getData().getPosition().equals(position)) {
                childMenu.add(mu);
                //递归遍历下一级
            } else {
                if (!CollectionUtils.isEmpty(mu.getChildList())) {
                    treeMenuList(childMenu, mu.getChildList(), position);
                }
            }

        }
        return childMenu;
    }

    /**
     * 组装数据
     *
     * @param root
     */
    public static Map<String, Map<String, List<String>>> ZZ(ManyTreeNode root) {
        Stack<ManyTreeNode> stack = new Stack<ManyTreeNode>();
        List<ManyTreeNode> result = new ArrayList<ManyTreeNode>();
        stack.push(root);
        while (!stack.isEmpty()) {
            ManyTreeNode top = stack.pop();
            result.add(top);
            List<ManyTreeNode> children = top.getChildList();
            if (children != null && children.size() > 0) {
                for (int i = children.size() - 1; i >= 0; i--) {
                    stack.push(children.get(i));
                }
            }
        }
        Map<String, Map<String, List<String>>> map = new HashMap<>();
        for (ManyTreeNode manyTreeNode : result) {
            TreeNode treeNode = manyTreeNode.getData();
            if ("root".equals(treeNode.getParentId())) {
                List<ManyTreeNode> childList = manyTreeNode.getChildList();
                Map<String, List<String>> childMap = new HashMap<>();
                for (ManyTreeNode node : childList) {
                    if (node.getData().getPosition().equals("2")) {
                        List<String> strings = new ArrayList<>();
                        if (!CollectionUtils.isEmpty(node.getChildList())) {
                            for (ManyTreeNode child : node.getChildList()) {
                                if (child.getData().getPosition().equals("3")) {
                                    strings.add(child.getData().getValue());
                                }
                            }
                            childMap.put(node.getData().getValue(), strings);
                        }
                    }
                }
                map.put(manyTreeNode.getData().getValue(), childMap);
            }
        }
        return map;
    }

    /**
     * 深度优先
     *
     * @param root
     */
    public static void SD(ManyTreeNode root) {
        Stack<ManyTreeNode> stack = new Stack<ManyTreeNode>();
        List<ManyTreeNode> result = new ArrayList<ManyTreeNode>();
        stack.push(root);
        Map<String, List<Map<String, List<String>>>> map;
        while (!stack.isEmpty()) {
            ManyTreeNode top = stack.pop();
            result.add(top);
            if (top.getData().getParentId().equals("root")) {

            }
            System.out.println(top.getData().getId());
            List<ManyTreeNode> children = top.getChildList();
            if (children != null && children.size() > 0) {
                for (int i = children.size() - 1; i >= 0; i--) {
                    stack.push(children.get(i));
                }
            }
        }
    }

    /**
     * 广度优先
     *
     * @param root
     */
    public static void GD(ManyTreeNode root) {
        Queue<ManyTreeNode> queue = new LinkedBlockingQueue<ManyTreeNode>();
        List<ManyTreeNode> result = new ArrayList<ManyTreeNode>();
        queue.add(root);
        while (!queue.isEmpty()) {
            ManyTreeNode first = queue.poll();
            result.add(first);
            List<ManyTreeNode> children = first.getChildList();
            if (children != null && children.size() > 0) {
                for (int i = 0; i < children.size(); i++) {
                    queue.add(children.get(i));
                }
            }
        }
    }

    /**
     * 递归
     *
     * @param manyTreeNode
     * @return
     */
    public static String iteratorTree(ManyTreeNode manyTreeNode) {
        StringBuilder buffer = new StringBuilder();
        buffer.append("\n");

        if (manyTreeNode != null) {
            for (ManyTreeNode index : manyTreeNode.getChildList()) {
                buffer.append(index.getData().getId() + ",");

                if (index.getChildList() != null && index.getChildList().size() > 0) {
                    buffer.append(iteratorTree(index));
                }
            }
        }

        buffer.append("\n");

        return buffer.toString();
    }

    /**
     * 递归获取某个父机构节点下面的所有子机构节点
     *
     * @param childOrg 要返回的结果
     * @param orgList  数据库查询出来的所有机构集合
     * @param position 位置
     *                 注:本身的机构节点不会添加进去
     */
    private static void orgRecursion(List<ManyTreeNode> childOrg, List<ManyTreeNode> orgList, String position) {
        for (ManyTreeNode org : orgList) {
            if (org != null) {
                //遍历出父id等于参数的id，add进子节点集合
                if (org.getData().getPosition().equals(position)) {
                    //递归遍历下一级
                    if (!CollectionUtils.isEmpty(org.getChildList())) {
                        orgRecursion(childOrg, org.getChildList(), org.getChildList().get(0).getData().getPosition());
                    }
                    //末级机构才添加进去(依自己业务定义)
                    if (org.getData().getPosition().equals("2")) {
                        childOrg.add(org);
                    }
                }
            }
        }
    }

    public static ManyTreeNode createManyTree() {
        ManyTreeNode manyRoot = new ManyTreeNode();
        // ---- root -----
        TreeNode root = new TreeNode();
        root.setId("root");
        root.setValue("root");
        root.setPosition("0");
        root.setParentId(null);
        manyRoot.setData(root);
        // ---- A1 ----
        ManyTreeNode manyA1 = new ManyTreeNode();
        TreeNode A1 = new TreeNode();
        A1.setId("A1");
        A1.setPosition("1");
        A1.setValue("100");
        A1.setParentId("root");
        manyA1.setData(A1);
        ManyTreeNode manyA2 = new ManyTreeNode();
        TreeNode A2 = new TreeNode();
        A2.setId("A2");
        A2.setPosition("1");
        A2.setValue("200");
        A2.setParentId("root");
        manyA2.setData(A2);
        ManyTreeNode manyA3 = new ManyTreeNode();
        TreeNode A3 = new TreeNode();
        A3.setId("A3");
        A3.setPosition("1");
        A3.setValue("300");
        A3.setParentId("root");
        manyA3.setData(A3);
        ArrayList<ManyTreeNode> listA = new ArrayList<>();
        listA.add(manyA1);
        listA.add(manyA2);
        listA.add(manyA3);
        manyRoot.setChildList(listA);
        //    ------ B1 -----
        ManyTreeNode manyB1 = new ManyTreeNode();
        TreeNode B1 = new TreeNode();
        B1.setParentId("A1");
        B1.setPosition("2");
        B1.setId("B1");
        B1.setValue("101");
        manyB1.setData(B1);
        ManyTreeNode manyB2 = new ManyTreeNode();
        TreeNode B2 = new TreeNode();
        B2.setParentId("A1");
        B2.setId("B2");
        B2.setPosition("2");
        B2.setValue("102");
        manyB2.setData(B2);
        ManyTreeNode manyB3 = new ManyTreeNode();
        TreeNode B3 = new TreeNode();
        B3.setParentId("A1");
        B3.setId("B3");
        B3.setPosition("2");
        B3.setValue("103");
        manyB3.setData(B3);
        ArrayList<ManyTreeNode> listB = new ArrayList<>();
        listB.add(manyB1);
        listB.add(manyB2);
        listB.add(manyB3);
        manyA1.setChildList(listB);
        // ----- c1 -----
        ManyTreeNode manyC1 = new ManyTreeNode();
        TreeNode C1 = new TreeNode();
        C1.setParentId("A2");
        C1.setId("C1");
        C1.setPosition("2");
        C1.setValue("201");
        manyC1.setData(C1);
        ManyTreeNode manyC2 = new ManyTreeNode();
        TreeNode C2 = new TreeNode();
        C2.setParentId("A2");
        C2.setPosition("2");
        C2.setId("C2");
        C2.setValue("202");
        manyC2.setData(C2);
        ManyTreeNode manyC3 = new ManyTreeNode();
        TreeNode C3 = new TreeNode();
        C3.setParentId("A2");
        C3.setPosition("2");
        C3.setId("C3");
        C3.setValue("203");
        manyC3.setData(C3);
        ArrayList<ManyTreeNode> listC = new ArrayList<>();
        listC.add(manyC1);
        listC.add(manyC2);
        listC.add(manyC3);
        manyA2.setChildList(listC);
        // D1
        ManyTreeNode manyD1 = new ManyTreeNode();
        TreeNode D1 = new TreeNode();
        D1.setParentId("A3");
        D1.setPosition("2");
        D1.setValue("301");
        D1.setId("D1");
        manyD1.setData(D1);
        ManyTreeNode manyD2 = new ManyTreeNode();
        TreeNode D2 = new TreeNode();
        D2.setParentId("A3");
        D2.setId("D2");
        D2.setPosition("2");
        D2.setValue("302");
        manyD2.setData(D2);
        ManyTreeNode manyD3 = new ManyTreeNode();
        TreeNode D3 = new TreeNode();
        D3.setParentId("A3");
        D3.setId("D3");
        D3.setPosition("2");
        D3.setValue("303");
        manyD3.setData(D3);
        ArrayList<ManyTreeNode> listD = new ArrayList<>();
        listD.add(manyD1);
        listD.add(manyD2);
        listD.add(manyD3);
        manyA3.setChildList(listD);
        // B1
        ManyTreeNode manyE1 = new ManyTreeNode();
        TreeNode E1 = new TreeNode();
        E1.setParentId("B1");
        E1.setId("E1");
        E1.setPosition("3");
        E1.setValue("104");
        manyE1.setData(E1);
        ManyTreeNode manyE2 = new ManyTreeNode();
        TreeNode E2 = new TreeNode();
        E2.setParentId("B1");
        E2.setId("E2");
        E2.setPosition("3");
        E2.setValue("105");
        manyE2.setData(E2);
        ManyTreeNode manyE3 = new ManyTreeNode();
        TreeNode E3 = new TreeNode();
        E3.setParentId("B1");
        E3.setId("E3");
        E3.setPosition("3");
        E3.setValue("106");
        manyE3.setData(E3);
        ArrayList<ManyTreeNode> listE = new ArrayList<>();
        listE.add(manyE1);
        listE.add(manyE2);
        listE.add(manyE3);
        manyB1.setChildList(listE);
        // B2
        ManyTreeNode manyF1 = new ManyTreeNode();
        TreeNode F1 = new TreeNode();
        F1.setParentId("B2");
        F1.setPosition("3");
        F1.setId("F1");
        F1.setValue("107");
        manyF1.setData(F1);
        ManyTreeNode manyF2 = new ManyTreeNode();
        TreeNode F2 = new TreeNode();
        F2.setParentId("B2");
        F2.setId("F2");
        F2.setPosition("3");
        F2.setValue("108");
        manyF2.setData(F2);
        ArrayList<ManyTreeNode> listF = new ArrayList<>();
        listF.add(manyF1);
        listF.add(manyF2);
        manyB2.setChildList(listF);
        // B3
        ManyTreeNode manyG1 = new ManyTreeNode();
        TreeNode G1 = new TreeNode();
        G1.setParentId("B3");
        G1.setId("G1");
        G1.setPosition("3");
        G1.setValue("109");
        manyG1.setData(G1);
        ManyTreeNode manyG2 = new ManyTreeNode();
        TreeNode G2 = new TreeNode();
        G2.setParentId("B3");
        G2.setPosition("3");
        G2.setId("G2");
        G2.setValue("110");
        manyG2.setData(G2);
        ArrayList<ManyTreeNode> listG = new ArrayList<>();
        listG.add(manyG1);
        listG.add(manyG2);
        manyB3.setChildList(listG);
        // C1
        ManyTreeNode manyH1 = new ManyTreeNode();
        TreeNode H1 = new TreeNode();
        H1.setParentId("C1");
        H1.setId("H1");
        H1.setPosition("3");
        H1.setValue("204");
        manyH1.setData(H1);
        ArrayList<ManyTreeNode> listH = new ArrayList<>();
        listH.add(manyH1);
        manyC1.setChildList(listH);
        // C2
        manyC2.setChildList(null);
        // C3
        ManyTreeNode manyI1 = new ManyTreeNode();
        TreeNode I1 = new TreeNode();
        I1.setParentId("C1");
        I1.setId("I1");
        I1.setPosition("3");
        I1.setValue("205");
        manyI1.setData(I1);
        ArrayList<ManyTreeNode> listI = new ArrayList<>();
        listI.add(manyI1);
        manyC3.setChildList(listI);
        // D1
        manyD1.setChildList(null);
        // D2
        ManyTreeNode manyJ1 = new ManyTreeNode();
        TreeNode J1 = new TreeNode();
        J1.setParentId("D2");
        J1.setId("J1");
        J1.setPosition("3");
        J1.setValue("304");
        manyJ1.setData(J1);
        ManyTreeNode manyJ2 = new ManyTreeNode();
        TreeNode J2 = new TreeNode();
        J2.setParentId("D2");
        J2.setId("J2");
        J2.setPosition("3");
        J2.setValue("305");
        manyJ2.setData(J2);
        ManyTreeNode manyJ3 = new ManyTreeNode();
        TreeNode J3 = new TreeNode();
        J3.setParentId("D2");
        J3.setId("J3");
        J3.setPosition("3");
        J3.setValue("306");
        manyJ3.setData(J3);
        ArrayList<ManyTreeNode> listJ = new ArrayList<>();
        listJ.add(manyJ1);
        listJ.add(manyJ2);
        listJ.add(manyJ3);
        manyD2.setChildList(listJ);
        // D3
        manyD3.setChildList(null);
        return manyRoot;

    }
}
